home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_std / native_array.e < prev    next >
Text File  |  2000-03-25  |  15KB  |  577 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. expanded class NATIVE_ARRAY[E]
  13. --
  14. -- This class gives access to the lowest level for arrays both
  15. -- for the C language and Java language.
  16. -- 
  17. -- Warning : using this class makes your Eiffel code non
  18. -- portable on other Eiffel systems.
  19. -- This class may also be modified in further release for a better
  20. -- interoperability between Java and C low level arrays.
  21. --
  22.  
  23. feature -- Basic features :
  24.  
  25.    element_sizeof: INTEGER is
  26.          -- The size in number of bytes for type `E'.
  27.       external "SmallEiffel"
  28.       end;
  29.  
  30.    calloc(nb_elements: INTEGER): like Current is
  31.          -- Allocate a new array of `nb_elements' of type `E'.
  32.          -- The new array is initialized with default values.
  33.       require
  34.          nb_elements > 0
  35.       external "SmallEiffel"
  36.       end;
  37.  
  38.    item(index: INTEGER): E is
  39.          -- To read an `item'.
  40.          -- Assume that `calloc' is already done and that `index'
  41.          -- is the range [0 .. nb_elements-1].
  42.       external "SmallEiffel"
  43.       end;
  44.  
  45.    put(element: E; index: INTEGER) is
  46.          -- To write an item.
  47.          -- Assume that `calloc' is already done and that `index'
  48.          -- is the range [0 .. nb_elements-1].
  49.       external "SmallEiffel"
  50.       end;
  51.  
  52. feature 
  53.  
  54.    realloc(old_nb_elts, new_nb_elts: INTEGER): like Current is
  55.          -- Assume Current is a valid NATIVE_ARRAY in range 
  56.          -- [0 .. `old_nb_elts'-1]. Allocate a bigger new array in
  57.          -- range [0 .. `new_nb_elts'-1].
  58.          -- Old range is copied in the new allocated array.
  59.          -- New items are initialized with default values.
  60.       require
  61.          is_not_null;
  62.          old_nb_elts > 0;
  63.          old_nb_elts < new_nb_elts
  64.       do
  65.          Result := calloc(new_nb_elts);
  66.          Result.copy_from(Current,old_nb_elts - 1);
  67.       end;
  68.  
  69. feature -- Comparison :
  70.  
  71.    memcmp(other: like Current; capacity: INTEGER): BOOLEAN is
  72.          -- True if all elements in range [0..capacity-1] are
  73.          -- identical using `equal'. Assume Current and `other' 
  74.          -- are big enough. 
  75.          -- See also `fast_memcmp'.
  76.       require
  77.          capacity > 0 implies other.is_not_null
  78.       local
  79.          i: INTEGER;
  80.       do
  81.          from
  82.             i := capacity - 1;
  83.          until
  84.             i < 0 or else not equal_like(item(i),other.item(i))
  85.          loop
  86.             i := i - 1;
  87.          end;
  88.          Result := i < 0;
  89.       end;
  90.  
  91.    fast_memcmp(other: like Current; capacity: INTEGER): BOOLEAN is
  92.          -- Same jobs as `memcmp' but uses infix "=" instead `equal'.
  93.       require
  94.          capacity > 0 implies other.is_not_null
  95.       local
  96.          i: INTEGER;
  97.       do
  98.          from
  99.             i := capacity - 1;
  100.          until
  101.             i < 0 or else item(i) /= other.item(i)
  102.          loop
  103.             i := i - 1;
  104.          end;
  105.          Result := i < 0;
  106.       end;
  107.  
  108.    deep_memcmp(other: like Current; capacity: INTEGER): BOOLEAN is
  109.          -- Same jobs as `memcmp' but uses `is_deep_equal' instead `equal'.
  110.       local
  111.          i: INTEGER;
  112.      e1, e2: like item;
  113.       do
  114.          from
  115.             i := capacity - 1;
  116.         Result := true;
  117.          until
  118.             not Result or else i < 0
  119.          loop
  120.         e1 := item(i);
  121.         e2 := other.item(i);
  122.         if e1 = e2 then
  123.         elseif e1 /= Void then
  124.            if e2 /= Void then
  125.           Result := e1.is_deep_equal(e2);
  126.            end;
  127.         end;
  128.             i := i - 1;
  129.          end;
  130.          Result := i < 0;
  131.       end;
  132.  
  133. feature -- Searching :
  134.  
  135.    index_of(element: like item; upper: INTEGER): INTEGER is
  136.          -- Give the index of the first occurrence of `element' using
  137.          -- `is_equal' for comparison.
  138.          -- Answer `upper + 1' when `element' is not inside.
  139.       require
  140.          upper >= -1
  141.       do
  142.          from  
  143.          until
  144.             Result > upper or else equal_like(element,item(Result))
  145.          loop
  146.             Result := Result + 1;
  147.          end;
  148.       end;
  149.  
  150.    fast_index_of(element: like item; upper: INTEGER): INTEGER is
  151.          -- Same as `index_of' but use basic `=' for comparison.
  152.       require
  153.          upper >= -1
  154.       do
  155.          from  
  156.          until
  157.             Result > upper or else element = item(Result)
  158.          loop
  159.             Result := Result + 1;
  160.          end;
  161.       end;
  162.  
  163.    has(element: like item; upper: INTEGER): BOOLEAN is
  164.          -- Look for `element' using `is_equal' for comparison.
  165.          -- Also consider `has' to choose the most appropriate.
  166.       require
  167.          upper >= -1
  168.       local
  169.          i: INTEGER;
  170.       do
  171.          from
  172.             i := upper;
  173.          until
  174.             Result or else i < 0
  175.          loop
  176.             Result := equal_like(element,item(i));
  177.             i := i - 1;
  178.          end;
  179.       end;
  180.  
  181.    fast_has(element: like item; upper: INTEGER): BOOLEAN is
  182.          -- Look for `element' using basic `=' for comparison.
  183.          -- Also consider `has' to choose the most appropriate.
  184.       require
  185.          upper >= -1
  186.       local
  187.          i: INTEGER;
  188.       do
  189.          from
  190.             i := upper;
  191.          until
  192.             i < 0 or else element = item(i)
  193.          loop
  194.             i := i - 1;
  195.          end;
  196.          Result := i >= 0;
  197.       end;
  198.  
  199.  
  200. feature -- Removing :
  201.  
  202.    remove_first(upper: INTEGER) is
  203.          -- Assume `upper' is a valid index.
  204.          -- Move range [1 .. `upper'] by 1 position left.
  205.       require
  206.          upper >= 0
  207.       local
  208.          i: INTEGER;
  209.       do
  210.          from 
  211.          until
  212.             i = upper
  213.          loop
  214.             put(item(i + 1),i);
  215.             i := i + 1;
  216.          end;
  217.       end;
  218.  
  219.    remove(index, upper: INTEGER) is
  220.          -- Assume `upper' is a valid index.
  221.          -- Move range [`index' + 1 .. `upper'] by 1 position left.
  222.       require
  223.          index >= 0;
  224.          index <= upper
  225.       local
  226.          i: INTEGER;
  227.       do
  228.          from 
  229.             i := index;
  230.          until
  231.             i = upper
  232.          loop
  233.             put(item(i + 1),i);
  234.             i := i + 1;
  235.          end;
  236.       end;
  237.  
  238. feature -- Replacing :
  239.  
  240.    replace_all(old_value, new_value: like item; upper: INTEGER) is
  241.          -- Replace all occurences of the element `old_value' by `new_value' 
  242.          -- using `is_equal' for comparison.
  243.          -- See also `fast_replace_all' to choose the apropriate one.
  244.       require
  245.          upper >= -1
  246.       local
  247.          i: INTEGER;
  248.       do
  249.          from
  250.             i := upper;
  251.          until
  252.             i < 0
  253.          loop
  254.             if equal_like(old_value,item(i)) then
  255.                put(new_value,i);
  256.             end;
  257.             i := i - 1;
  258.          end;
  259.       end;
  260.  
  261.  
  262.    fast_replace_all(old_value, new_value: like item; upper: INTEGER) is
  263.          -- Replace all occurences of the element `old_value' by `new_value' 
  264.          -- using basic `=' for comparison.
  265.          -- See also `replace_all' to choose the apropriate one.
  266.       require
  267.          upper >= -1
  268.       local
  269.          i: INTEGER;
  270.       do
  271.          from
  272.             i := upper;
  273.          until
  274.             i < 0
  275.          loop
  276.             if old_value = item(i) then
  277.                put(new_value,i);
  278.             end;
  279.             i := i - 1;
  280.          end;
  281.       end;
  282.  
  283. feature -- Adding :
  284.  
  285.    copy_at(at: INTEGER; src: like Current; src_capacity: INTEGER) is
  286.          -- Copy range [0 .. `src_capacity' - 1] of `src' to range 
  287.      -- [`at' .. `at + src_capacity'] of `Current'. 
  288.      -- No subscript checking.
  289.       require
  290.          at >= 0;
  291.          src_capacity >= 0;
  292.       local
  293.          i1, i2: INTEGER;
  294.       do
  295.          from
  296.             i1 := at;
  297.          until
  298.             i2 = src_capacity
  299.          loop
  300.             put(src.item(i2),i1);
  301.             i2 := i2 + 1;
  302.             i1 := i1 + 1;
  303.          end;
  304.       end;
  305.  
  306.    copy_slice(at: INTEGER; src: like Current; src_min, src_max: INTEGER) is
  307.          -- Copy range [`src_min' .. `src_max'] of `src' to range 
  308.          -- [`at' .. `at + src_max - src_min - 1'] of `Current'.
  309.      -- No subscript checking.
  310.       require
  311.          at >= 0;
  312.          src_min <= src_max + 1
  313.       local
  314.          i1, i2: INTEGER;
  315.       do
  316.          from
  317.             i1 := at;
  318.         i2 := src_min;
  319.          until
  320.             i2 > src_max
  321.          loop
  322.             put(src.item(i2),i1);
  323.             i2 := i2 + 1;
  324.             i1 := i1 + 1;
  325.          end;
  326.       end;
  327.  
  328. feature -- Other :
  329.  
  330.    set_all_with(v: like item; upper: INTEGER) is
  331.          -- Set all elements in range [0 .. upper] with
  332.          -- value `v'.
  333.       local
  334.          i: INTEGER;
  335.       do
  336.          from
  337.             i := upper;
  338.          until
  339.             i < 0
  340.          loop
  341.             put(v,i);
  342.             i := i - 1;
  343.          end;
  344.       end;
  345.  
  346.    clear_all(upper: INTEGER) is
  347.          -- Set all elements in range [0 .. `upper'] with
  348.          -- the default value.
  349.       local
  350.          v: E;
  351.          i: INTEGER;
  352.       do
  353.          from
  354.             i := upper;
  355.          until
  356.             i < 0
  357.          loop
  358.             put(v,i);
  359.             i := i - 1;
  360.          end;
  361.       end;
  362.  
  363.    clear(lower, upper: INTEGER) is
  364.          -- Set all elements in range [`lower' .. `upper'] with
  365.          -- the default value
  366.       require
  367.          lower >= 0;
  368.          upper >= lower
  369.       local
  370.          v: E;
  371.          i: INTEGER;
  372.       do
  373.          from
  374.             i := lower
  375.          until
  376.             i > upper
  377.          loop
  378.             put(v, i);
  379.             i := i + 1;
  380.          end
  381.       end
  382.  
  383.    copy_from(model: like Current; upper: INTEGER) is
  384.          -- Assume `upper' is a valid index both in Current and `model'.
  385.       local
  386.          i: INTEGER;
  387.       do
  388.          from
  389.             i := upper;
  390.          until
  391.             i < 0
  392.          loop
  393.             put(model.item(i),i);
  394.             i := i - 1;
  395.          end;
  396.       end;
  397.  
  398.    deep_twin_from(capacity: INTEGER): like Current is
  399.      -- To implement `deep_twin'. Allocate a new array of 
  400.      -- `capacity' initialized with `deep_twin'.
  401.          -- Assume `capacity' is valid both in Current and `model'.
  402.       require
  403.      capacity >= 0
  404.       local
  405.          i: INTEGER;
  406.      element: like item;
  407.       do
  408.      if capacity > 0 then
  409.         from
  410.            Result := calloc(capacity);
  411.            i := capacity - 1;
  412.         until
  413.            i < 0
  414.         loop
  415.            element := item(i);
  416.            if element /= Void then
  417.           element := element.deep_twin;
  418.            end;
  419.            Result.put(element,i);
  420.            i := i - 1;
  421.         end;
  422.      end;
  423.       end;
  424.  
  425.    move(lower, upper, offset: INTEGER) is
  426.          -- Move range [`lower' .. `upper'] by `offset' positions.
  427.          -- Freed positions are not initialized to default values.
  428.       require
  429.          lower >= 0;
  430.          upper >= lower;
  431.          lower + offset >= 0
  432.       local
  433.          i: INTEGER;
  434.       do
  435.          if offset = 0 then
  436.          elseif offset < 0 then
  437.             from
  438.                i := lower;
  439.             until
  440.                i > upper
  441.             loop
  442.                put(item(i), i + offset);
  443.                i := i + 1;
  444.             end
  445.          else
  446.             from
  447.                i := upper;
  448.             until
  449.                i < lower
  450.             loop
  451.                put(item(i), i + offset);
  452.                i := i - 1;
  453.             end
  454.          end
  455.       end
  456.  
  457.    nb_occurrences(element: like item; upper: INTEGER): INTEGER is
  458.          -- Number of occurrences of `element' in range [0..upper]
  459.          -- using `equal' for comparison.
  460.          -- See also `fast_nb_occurrences' to chose the apropriate one.
  461.       local
  462.          i: INTEGER;
  463.       do
  464.          from  
  465.             i := upper;
  466.          until
  467.             i < 0
  468.          loop
  469.             if equal_like(element,item(i)) then
  470.                Result := Result + 1;
  471.             end;
  472.             i := i - 1;
  473.          end;
  474.       end;
  475.  
  476.    fast_nb_occurrences(element: like item; upper: INTEGER): INTEGER is
  477.          -- Number of occurrences of `element' in range [0..upper]
  478.          -- using basic "=" for comparison.
  479.          -- See also `fast_nb_occurrences' to chose the apropriate one.
  480.       local
  481.          i: INTEGER;
  482.       do
  483.          from  
  484.             i := upper;
  485.          until
  486.             i < 0
  487.          loop
  488.             if element = item(i) then
  489.                Result := Result + 1;
  490.             end;
  491.             i := i - 1;
  492.          end;
  493.       end;
  494.  
  495.    all_default(upper: INTEGER): BOOLEAN is
  496.          -- Do all items in range [0 .. `upper'] have their type's
  497.      -- default value?
  498.       require
  499.          upper >= -1
  500.       local
  501.          i: INTEGER;
  502.          model: like item;
  503.       do
  504.          from
  505.             Result := true;
  506.             i := upper;
  507.          until
  508.             i < 0 or else not Result
  509.          loop
  510.             Result := model = item(i)
  511.             i := i - 1;
  512.          end;
  513.       end;
  514.  
  515.    all_cleared(upper: INTEGER): BOOLEAN is
  516.       obsolete "The new name of this feature is `all_default'."
  517.       do
  518.      Result := all_default(upper);
  519.       end;
  520.  
  521. feature -- Interfacing with C :
  522.  
  523.    to_external: POINTER is
  524.          -- Gives access to the C pointer on the area of storage.
  525.       do
  526.          Result := to_pointer;
  527.       end;
  528.  
  529.    from_pointer(pointer: POINTER): like Current is
  530.          -- Convert `pointer' into Current type.
  531.       external "SmallEiffel"
  532.       end;
  533.  
  534.    is_not_null: BOOLEAN is
  535.       do
  536.          Result := to_pointer.is_not_null;
  537.       end;
  538.  
  539.    is_not_void: BOOLEAN is
  540.       obsolete "This feature will be soon removed. %
  541.                %Since release -0.78, the new name for this feature %
  542.                %is `is_not_null'. Please, update your code."
  543.       do
  544.          Result := is_not_null;
  545.       end;
  546.  
  547. feature -- For C only :
  548.  
  549.    bytes_malloc(nb_bytes: INTEGER): like Current is
  550.       obsolete "This dangerous feature will be soon removed. %
  551.                %Please, update your code."
  552.       external "C_InlineWithoutCurrent"
  553.       alias "malloc"
  554.       end;
  555.  
  556. feature {NONE}
  557.  
  558.    frozen equal_like(e1, e2: like item): BOOLEAN is
  559.          -- Note: this feature is called to avoid calling `equal'
  560.          -- on expanded types (no automatic conversion to 
  561.          -- corresponding reference type).
  562.       do
  563.          if e1.is_basic_expanded_type then
  564.             Result := e1 = e2;
  565.          elseif e1.is_expanded_type then
  566.             Result := e1.is_equal(e2);
  567.          elseif e1 = e2 then
  568.             Result := true;
  569.          elseif e1 = Void or else e2 = Void then
  570.          else
  571.             Result := e1.is_equal(e2);
  572.          end;
  573.       end;
  574.  
  575. end -- NATIVE_ARRAY[E]
  576.  
  577.